package com.sm.chatinputlibrary.utils;

import android.content.Context;
import android.media.MediaRecorder;
import android.util.Log;

import com.scorpio.baselibrary.utils.FileUtil;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * created by zhud on 2019/7/18
 */
public class RecorderUtil {
    private static final String TAG = "RecorderUtil";

    private String mFileName = null;
    private MediaRecorder mRecorder = null;
    private long startTime;
    private long timeInterval;
    private boolean isRecording;
    private Context context;
    private RecorderProcessListener recorderProcessListener;

    public RecorderUtil(Context context) {
        this.context = context;
        mFileName = FileUtil.getDiskCachePath(context) + "/tempAudio";
    }

    public void setRecorderProcessListener(RecorderProcessListener recorderProcessListener) {
        this.recorderProcessListener = recorderProcessListener;
    }

    /**
     * 开始录音
     */
    public void startRecording() {
        if (mFileName == null) return;
        if (isRecording) {
            mRecorder.release();
            mRecorder = null;
        }
        new File(FileUtil.getDiskCachePath(context)).mkdirs();
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mRecorder.setOutputFile(mFileName);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        startTime = System.currentTimeMillis();
        try {
            mRecorder.prepare();
            mRecorder.start();
            isRecording = true;
            new Thread(sendRecordDbRunnable).start();
        } catch (Exception e) {
            Log.e(TAG, "prepare() failed");
            if (recorderProcessListener != null) recorderProcessListener.onRecorderError();
        }

    }

    private static final int BASE = 1;

    private synchronized int getDb() {
        if (mRecorder != null) {
            double ratio = (double) mRecorder.getMaxAmplitude() / BASE;
            double db = 0;// 分贝
            if (ratio > 1)
                db = 20 * Math.log10(ratio);
            return (int) (db / 10);
        }
        return 0;
    }

    /**
     * 停止录音
     */
    public void stopRecording() {
        if (mFileName == null) return;
        timeInterval = System.currentTimeMillis() - startTime;
        try {
            if (timeInterval > 1000) {
                mRecorder.stop();
            }
            mRecorder.release();
            mRecorder = null;
            isRecording = false;
        } catch (Exception e) {
            Log.e(TAG, "release() failed");
        }

    }


    /**
     * 获取录音文件
     */
    public byte[] getDate() {
        if (mFileName == null) return null;
        try {
            return readFile(new File(mFileName));
        } catch (IOException e) {
            Log.e(TAG, "read file error" + e);
            return null;
        }
    }

    /**
     * 获取录音文件地址
     */
    public String getFilePath() {
        return mFileName;
    }


    /**
     * 获取录音时长,单位秒
     */
    public long getTimeInterval() {
        return timeInterval / 1000;
    }


    /**
     * 将文件转化为byte[]
     *
     * @param file 输入文件
     */
    private static byte[] readFile(File file) throws IOException {
        // Open file
        RandomAccessFile f = new RandomAccessFile(file, "r");
        try {
            // Get and check length
            long longlength = f.length();
            int length = (int) longlength;
            if (length != longlength)
                throw new IOException("File size >= 2 GB");
            // Read file and return data
            byte[] data = new byte[length];
            f.readFully(data);
            return data;
        } finally {
            f.close();
        }
    }

    Runnable sendRecordDbRunnable = new Runnable() {
        @Override
        public void run() {
            while (isRecording) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (recorderProcessListener != null) {
                    recorderProcessListener.onRecorderProcess(getDb());
                }
            }
        }
    };

    public boolean isRecording() {
        return isRecording;
    }

    public interface RecorderProcessListener {
        /**
         * @param voiceVolume 音量 max=100
         */
        void onRecorderProcess(int voiceVolume);

        void onRecorderError();
    }
}
